package com.tobeface.wechat.request;

import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import com.tobeface.modules.lang.Requires;

import java.util.Map;

/**
 * @author loudyn
 */
public class WeChatRequest {

    public static final String USER_AGENT = "Tface4wechat (v1)";

    public enum Verb {
        GET, POST
    }

    private final String url;
    private final Verb verb;
    private Map<String, String> headers = Maps.newHashMap();
    private Map<String, String> queryParams = Maps.newHashMap();
    private Map<String, String> bodyParams = Maps.newHashMap();
    private Object entity;

    private int connectTimeoutMillis;
    private int waitTimeoutMillis;


    /**
     * @param url
     * @param verb
     */
    WeChatRequest(String url, Verb verb) {
        Requires.hasText(url);
        Requires.notNull(verb);
        this.url = url;
        this.verb = verb;
    }

    /**
     * @param name
     * @param val
     * @return
     */
    public WeChatRequest addHeader(String name, String val) {
        this.headers.put(name, val);
        return this;
    }

    /**
     * @param name
     * @param val
     * @return
     */
    public WeChatRequest addQueryParam(String name, String val) {
        this.queryParams.put(name, val);
        return this;
    }

    /**
     * @param name
     * @param val
     * @return
     */
    public WeChatRequest addBodyParam(String name, String val) {
        if (getVerb() != Verb.POST) {
            throw new IllegalStateException("Not Post Verb can't accept bodyParams!");
        }

        if (null != entity) {
            throw new IllegalStateException("Entity is not null,pls make sure using the entity!");
        }
        this.bodyParams.put(name, val);
        return this;
    }

    /**
     * @param entity
     * @return
     */
    public WeChatRequest entity(Object entity) {
        if (getVerb() != Verb.POST) {
            throw new IllegalStateException("Not Post Verb can't accept entity!");
        }

        if (!bodyParams.isEmpty()) {
            throw new IllegalStateException("BodyParams is not empty,pls make sure using the bodyParams!");
        }
        this.entity = entity;
        return this;
    }

    /**
     * @param connectTimeoutMillis
     * @return
     */
    public WeChatRequest connectTimeoutMillis(int connectTimeoutMillis) {
        this.connectTimeoutMillis = connectTimeoutMillis;
        return this;
    }

    /**
     * @param waitTimeoutMillis
     * @return
     */
    public WeChatRequest waitTimeoutMillis(int waitTimeoutMillis) {
        this.waitTimeoutMillis = waitTimeoutMillis;
        return this;
    }

    /**
     * @return
     */
    public String getUrl() {
        return url;
    }

    /**
     * @return
     */
    public String getQueryUrl() {
        return WeChatRequestURLBuilder.buildQueryUrl(this);
    }

    /**
     * @return
     */
    public Verb getVerb() {
        return verb;
    }

    /**
     * @return
     */
    public Map<String, String> getHeaders() {
        return ImmutableMap.copyOf(this.headers);
    }

    /**
     * @return
     */
    public Map<String, String> getQueryParams() {
        return ImmutableMap.copyOf(this.queryParams);
    }

    /**
     * @return
     */
    public Map<String, String> getBodyParams() {
        return ImmutableMap.copyOf(this.getBodyParams());
    }

    /**
     * @return
     */
    public Object getEntity() {
        return entity;
    }

    /**
     * @return
     */
    public int getConnectTimeoutMillis() {
        return connectTimeoutMillis;
    }

    /**
     * @return
     */
    public int getWaitTimeoutMillis() {
        return waitTimeoutMillis;
    }

    /**
     * @return
     */
    public static WeChatRequest of(String url, Verb verb) {
        return new WeChatRequest(url, verb);
    }
}
